home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr27 / gs26.zip / GS_FONTS.PS < prev    next >
Text File  |  1993-05-06  |  17KB  |  528 lines

  1. %    Copyright (C) 1990, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2. %    Distributed by Free Software Foundation, Inc.
  3. %
  4. % This file is part of Ghostscript.
  5. %
  6. % Ghostscript is distributed in the hope that it will be useful, but
  7. % WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. % to anyone for the consequences of using it or for whether it serves any
  9. % particular purpose or works at all, unless he says so in writing.  Refer
  10. % to the Ghostscript General Public License for full details.
  11. %
  12. % Everyone is granted permission to copy, modify and redistribute
  13. % Ghostscript, but only under the conditions described in the Ghostscript
  14. % General Public License.  A copy of this license is supposed to have been
  15. % given to you along with Ghostscript so you can know your rights and
  16. % responsibilities.  It should be in a file named COPYING.  Among other
  17. % things, the copyright notice and this notice must be preserved on all
  18. % copies.
  19.  
  20. % Font initialization for Ghostscript.
  21.  
  22. % The standard representation for PostScript compatible fonts is described
  23. % in the book "Adobe Type 1 Font Format", published by Adobe Systems Inc.
  24. % We don't attempt to document this representation here.
  25. % Ghostscript uses Type 1 fonts, except that the external form doesn't use
  26. % eexec encryption and may not even use CharString encryption.
  27.  
  28.  
  29. % Define the default font.
  30. /defaultfontname /Ugly def
  31.  
  32. % Load the font name -> font file name map.
  33. userdict /Fontmap FontDirectory maxlength dict put
  34. /.loadFontmap        % <filename>
  35.  { 2 dict begin
  36.      mark Fontmap
  37.      /;
  38.       { % The stack contains a mark, the dictionary, the font name,
  39.         % the file or alias name, and possibly additional information
  40.     % about the font.
  41.     counttomark 3 sub { pop } repeat .growput
  42.     Fontmap
  43.       } bind def
  44.      3 -1 roll run
  45.    end
  46.    pop pop        % pop the mark and the copy of the dictionary
  47.  } bind def
  48. (Fontmap) .loadFontmap
  49.  
  50. % Ghostscript optionally can load individual CharStrings as they are needed.
  51. % (This is intended primarily for machines with very small memories.)
  52. % This happens if DISKFONTS is true.  In this case, we define another
  53. % dictionary parallel to FontDirectory that retains an open file
  54. % for every font loaded.
  55. /FontFileDirectory 10 dict def
  56.  
  57. % Define an augmented version of .buildfont1 that inserts UnderlinePosition
  58. % and UnderlineThickness entries in FontInfo if they aren't there already.
  59. % (This works around the incorrect assumption, made by many word processors,
  60. % that these entries are present in the built-in fonts.)
  61. /.buildfont1x
  62.  { dup /FontInfo known not
  63.     { dup /FontInfo 2 dict .growput }
  64.    if
  65.    dup dup /FontInfo get dup dup
  66.    /UnderlinePosition known exch /UnderlineThickness known and
  67.     { pop pop        % entries already present
  68.     }
  69.     { dup length 2 add dict copy
  70.       dup /UnderlinePosition known not
  71.        { dup /UnderlinePosition 3 index /FontBBox get
  72.          1 get 2 div put        % 1/2 the font descent
  73.        }
  74.       if
  75.       dup /UnderlineThickness known not
  76.        { dup /UnderlineThickness 3 index /FontBBox get
  77.          dup 3 get exch 1 get sub 20 div put    % 1/20 the font height
  78.        }
  79.       if
  80.       1 index /FontInfo get wcheck not { readonly } if
  81.       /FontInfo exch put
  82.     }
  83.    ifelse .buildfont1
  84.  } bind def
  85. % Define definefont.  This is a procedure built on a set of operators
  86. % that do all the error checking and key insertion.
  87. mark
  88.     /.buildfont0 where { pop 0 /.buildfont0 load } if
  89.     /.buildfont1 where { pop 1 /.buildfont1x load } if
  90.     /.buildfont3 where { pop 3 /.buildfont3 load } if
  91. dicttomark /.buildfontdict exch def
  92. /definefont
  93.  { 1 dict begin count /d exch def    % save stack depth in case of error
  94.     {        % Check for disabled platform fonts.
  95.       NOPLATFONTS
  96.        { dup maxlength 1 index length sub 2 lt { dup .growdict } if
  97.      dup /ExactSize 0 put
  98.        }
  99.       if
  100.       dup /FontType get //.buildfontdict exch get exec
  101.       DISKFONTS
  102.        { FontFileDirectory 2 index known
  103.           { dup /FontFile FontFileDirectory 4 index get .growput
  104.       }
  105.      if
  106.        }
  107.       if
  108.       readonly
  109.     }
  110.    stopped
  111.     { count d sub { pop } repeat end /invalidfont signalerror }
  112.     { end dup FontDirectory 4 2 roll .growput }
  113.    ifelse
  114.  } odef
  115.  
  116.  
  117. % Ghostscript optionally can load individual CharStrings as they are needed.
  118. % (This is intended primarily for machines with very small memories.)
  119. % Initially, the character definition is the file position of the definition;
  120. % this gets replaced with the actual CharString.
  121. % Note that if we are loading characters lazily, CharStrings is writable.
  122.  
  123. % _Cstring must be long enough to hold the longest CharString for
  124. % a character defined using seac.  This is lenIV + 4 * 5 (for the operands
  125. % of sbw, assuming div is not used) + 2 (for sbw) + 3 * 5 (for the operands
  126. % of seac other than the character codes) + 2 * 2 (for the character codes)
  127. % + 2 (for seac), i.e., lenIV + 43.
  128.  
  129. /_Cstring 60 string def
  130.  
  131. % When we initially load the font, we call
  132. %    <index|charname> <length> <readproc> cskip_C
  133. % to skip over each character definition and return the file position instead.
  134. % This substitutes for the procedure
  135. %    <index|charname> <length> string currentfile exch read[hex]string pop
  136. %      [encrypt]
  137. % What we actually store is fileposition * 1000 + length,
  138. %   negated if the string is stored in binary form.
  139.  
  140. % Older fonts use skip_C rather than cskip_C.
  141. % skip_C takes /readstring or /readhexstring as its third argument,
  142. % instead of the entire reading procedure.
  143. /skipproc_C {string currentfile exch readstring pop} cvlit def
  144. /skip_C
  145.  { //skipproc_C dup 3 4 -1 roll put cvx readonly cskip_C
  146.  } bind def
  147. /cskip_C
  148.  { exch dup 1000 ge 3 index type /nametype ne or
  149.     { % This is a Subrs string, or the string is so long we can't represent
  150.       % its length.  Load it now.
  151.       exch exec
  152.     }
  153.     { % Record the position and length, and skip the string.
  154.       dup currentfile fileposition 1000 mul add
  155.       2 index 3 get /readstring cvx eq { neg } if
  156.       3 1 roll
  157.       dup _Cstring length idiv
  158.        { currentfile _Cstring 3 index 3 get exec pop pop
  159.        } repeat
  160.       _Cstring length mod _Cstring exch 0 exch getinterval
  161.       currentfile exch 3 -1 roll 3 get exec pop pop
  162.     }
  163.    ifelse
  164.  } bind def
  165.  
  166. % Type1BuildGlyph calls load_C to actually load the character definition.
  167.  
  168. /load_C        % <charname> <fileposandlength> -> -
  169.  { dup abs 1000 idiv FontFile exch setfileposition
  170.    CharStrings 3 1 roll
  171.    dup 0 lt
  172.     { neg 1000 mod string FontFile exch readstring }
  173.     { 1000 mod string FontFile exch readhexstring }
  174.    ifelse pop
  175. % If the CharStrings aren't encrypted on the file, encrypt now.
  176.    Private /-| get 0 get
  177.    dup type /nametype ne { dup length 5 sub 5 exch getinterval exec } { pop } ifelse
  178.    dup 4 1 roll put
  179. % If the character is defined with seac, load its components now.
  180.    mark exch seac_C
  181.    counttomark
  182.     { StandardEncoding exch get dup CharStrings exch get
  183.       dup type /integertype eq { load_C } { pop pop } ifelse
  184.     } repeat
  185.    pop        % the mark
  186.  } bind def
  187.  
  188. /seac_C        % charstring -> achar bchar ..or nothing..
  189.  { dup length _Cstring length le
  190.     { 4330 exch _Cstring type1decrypt exch pop
  191.       dup dup length 2 sub 2 getinterval <0c06> eq    % seac
  192.        { dup length
  193.          Private /lenIV known { Private /lenIV get } { 4 } ifelse
  194.      exch 1 index sub getinterval
  195. % Parse the string just enough to extract the seac information.
  196. % We assume that the only possible operators are hsbw, sbw, and seac,
  197. % and that there are no 5-byte numbers.
  198.      mark 0 3 -1 roll
  199.       { exch
  200.          { { dup 32 lt
  201.               { pop 0 }
  202.           { dup 247 lt
  203.              { 139 sub 0 }
  204.              { dup 251 lt
  205.             { 247 sub 256 mul 108 add 1 1 }
  206.             { 251 sub -256 mul -108 add -1 1 }
  207.                ifelse
  208.              }
  209.             ifelse
  210.           }
  211.          ifelse
  212.            }            % 0
  213.            { mul add 0 }        % 1
  214.          }
  215.         exch get exec
  216.       }
  217.      forall pop
  218.      counttomark 1 add 2 roll cleartomark    % pop all but achar bchar
  219.        }
  220.        { pop    % not seac
  221.        }
  222.       ifelse
  223.     }
  224.     { pop    % punt
  225.     }
  226.    ifelse
  227.  } bind def
  228.  
  229. % Define an auxiliary procedure for loading a font.
  230. % If DISKFONTS is true and the body of the font is not encrypted with eexec:
  231. %    - Prevent the CharStrings from being made read-only.
  232. %    - Substitute a different CharString-reading procedure.
  233. % (eexec disables this because the implicit 'systemdict begin' hides
  234. % the redefinitions that make the scheme work.)
  235. % We assume that:
  236. %    - The magic procedures (-|, -!, |-, and |) are defined with
  237. %    executeonly or readonly;
  238. %    - The contents of the reading procedures are as defined in bdftops.ps;
  239. %    - The font ends with
  240. %    <font> <Private> <CharStrings>
  241. %    readonly put noaccess|readonly put
  242. 4 dict begin
  243.  /dict            % leave room for FontFile
  244.   { 1 add dict
  245.   } bind def
  246.  /executeonly        % for reading procedures
  247.   { readonly
  248.   } def
  249.  /noaccess        % for Subrs strings and Private dictionary
  250.   { readonly
  251.   } def
  252.  /readonly        % for procedures and CharStrings dictionary
  253.   {    % We want to take the following non-standard actions here:
  254.       %   - If the operand is the CharStrings dictionary, do nothing;
  255.     %   - If the operand is a number (a file position replacing the
  256.     %    actual CharString), do nothing;
  257.     %   - If the operand is either of the reading procedures (-| or -!),
  258.     %    substitute a different one.
  259.     dup type /dicttype eq        % CharStrings or Private
  260.      { 1 index /CharStrings ne { readonly } if }
  261.      { dup type /arraytype eq        % procedure or data array
  262.         { dup length 5 ge 1 index xcheck and
  263.        { dup 0 get /string eq
  264.          1 index 1 get /currentfile eq and
  265.          1 index 2 get /exch eq and
  266.          1 index 3 get dup /readstring eq exch /readhexstring eq or and
  267.          1 index 4 get /pop eq and
  268.           { /cskip_C cvx 2 packedarray cvx
  269.           }
  270.           { readonly
  271.           }
  272.          ifelse
  273.        }
  274.        { readonly
  275.        }
  276.       ifelse
  277.     }
  278.     { dup type /stringtype eq    % must be a Subr string
  279.        { readonly }
  280.       if
  281.     }
  282.        ifelse
  283.      }
  284.     ifelse
  285.   } bind def
  286. currentdict end readonly /.loadfontdict exch def
  287. /.loadfont        % <file> .loadfont ->
  288.  { mark exch systemdict begin
  289.    DISKFONTS { .loadfontdict begin } if
  290.    % We really would just like systemdict on the stack,
  291.    % but fonts produced by Fontographer require a writable dictionary....
  292.    8 dict begin        % garbage
  293.     % We can't just use `run', because we want to check for
  294.     % .PFB files.  We can't save the packing status anywhere,
  295.     % so we need two separate control paths.
  296.     % Also, we would like to use `false /PFBDecode filter',
  297.     % but this occasionally produces a whitespace character as
  298.     % the first of an eexec section, so we can't do it.
  299.     % Finally, since the interpreter doesn't currently automatically
  300.     % close an input file when the file reaches EOF (unless it's
  301.     % the interpreter's current input file), we must explicitly
  302.     % close the real file if we used a PFB filter.
  303.    currentpacking
  304.     { false setpacking
  305.        { dup read not { -1 } if
  306.          2 copy unread 16#80 eq
  307.       { dup true /PFBDecode filter cvx exec closefile }
  308.       { cvx exec }
  309.      ifelse
  310.        } stopped    % split up `execute'
  311.       true setpacking
  312.       $error /newerror get and {handleerror} if
  313.     }
  314.     {  { dup read not { -1 } if
  315.          2 copy unread 16#80 eq
  316.       { dup true /PFBDecode filter cvx exec closefile }
  317.       { cvx exec }
  318.      ifelse
  319.        } execute
  320.     }
  321.    ifelse
  322.    DISKFONTS { end } if
  323.    end end cleartomark
  324.  } bind def
  325.  
  326. % Define a procedure for defining aliased fonts.
  327. % We just copy the original font, changing the FontName.
  328. /.aliasfont        % <name> <font> -> <newFont>
  329.  { dup length 2 add dict
  330.    dup 3 -1 roll { 1 index /FID eq { pop pop } { put dup } ifelse } forall
  331.    /FontName 3 index put
  332.    definefont
  333.  } odef % bind def
  334.  
  335. % Define findfont so it tries to load a font if it's not found.
  336. /findfont
  337.  {    % Since PostScript has no concept of goto, or even blocks with
  338.     % exits, we use a loop as a way to get an exitable scope.
  339.     % The loop is never executed more than twice.
  340.     {
  341.     dup FontDirectory exch known        % Already loaded?
  342.      { FontDirectory exch get exit }
  343.     if
  344.  
  345.     dup Fontmap exch known not    % Unknown font name.
  346.      { dup defaultfontname eq
  347.         { (Default font ) print cvx =only
  348.           ( not found in Fontmap!  Giving up.\n) print flush
  349.           1 .quit
  350.         } if
  351.        QUIET not
  352.         { (Substituting ) print defaultfontname cvx =only
  353.           ( for unknown font ) print dup == flush
  354.         } if
  355.        defaultfontname findfont .aliasfont exit
  356.      }
  357.     if
  358.  
  359.     dup Fontmap exch get
  360.  
  361.     % Check for a font alias.
  362.     dup type /nametype eq
  363.      { findfont .aliasfont exit
  364.      }
  365.     if
  366.  
  367.     % If we can't open the file, substitute for the font.
  368.     findlibfile
  369.      { % Stack: fontname fontfilename fontfile
  370.        DISKFONTS
  371.         { 1 index (r) file
  372.           FontFileDirectory exch 4 index exch .growput
  373.         }
  374.        if
  375.        QUIET not
  376.         { (Loading ) print 2 index =only
  377.           ( font from ) print exch print (... ) print flush }
  378.         { exch pop }
  379.        ifelse
  380.        .loadfont
  381.        QUIET not
  382.         { vmstatus 3 { =only ( ) print } repeat
  383.           (done.\n) print flush
  384.         } if
  385.        % Check to make sure the font was actually loaded.
  386.        dup FontDirectory exch known { findfont exit } if
  387.  
  388.        (Loading ) print dup cvx =only
  389.        ( font failed, substituting ) print defaultfontname cvx =only
  390.        (.\n) print flush
  391.        defaultfontname findfont .aliasfont exit
  392.      }
  393.     if
  394.  
  395.     % findlibfile failed, substitute the default font.
  396.     % Stack: fontname fontfilename
  397.     (Can't find \(or can't open\) font file ) print print
  398.     dup defaultfontname eq
  399.      { ( for default font \() print cvx =only
  400.        (\)!  Giving up.\n) print flush 1 .quit
  401.      }
  402.      { ( for font ) print dup cvx =only
  403.        (, substituting ) print defaultfontname cvx =only
  404.        (.\n) print flush
  405.        defaultfontname findfont .aliasfont
  406.      }
  407.     ifelse
  408.     exit
  409.  
  410.     } loop        % end of loop
  411.  
  412.  } odef % bind def
  413.  
  414.  
  415. % The CharStrings are a dictionary in which the key is the character name,
  416. % and the value is a compressed and encrypted representation of a path.
  417. % For detailed information, see the book "Adobe Type 1 Font Format",
  418. % published by Adobe Systems Inc.
  419.  
  420. % Here are the BuildChar and BuildGlyph implementation for Type 1 fonts.
  421. % The names Type1BuildChar and Type1BuildGlyph are known to the interpreter.
  422.  
  423. /Type1BuildChar
  424.  { 1 index /Encoding get exch get Type1BuildGlyph
  425.  } bind def
  426. /Type1BuildGlyph
  427.  { exch begin
  428.     dup CharStrings exch .knownget not
  429.      { QUIET not
  430.         { (Substituting .notdef for ) print = flush
  431.     } { pop } ifelse
  432.        /.notdef CharStrings /.notdef get
  433.      } if
  434.     % stack: charname charstring
  435.     PaintType 0 ne
  436.      { 1 setmiterlimit 1 setlinejoin 1 setlinecap
  437.        currentdict /StrokeWidth .knownget not { 0 } if
  438.        setlinewidth
  439.      } if
  440.     dup type /stringtype eq        % encoded outline
  441.      { outline_C
  442.      }
  443.      { dup type /integertype eq        % file position for lazy loading
  444.         { 1 index exch load_C dup CharStrings exch get outline_C
  445.     }
  446.     {                % PostScript procedure
  447.       currentdict end systemdict begin begin   exec   end
  448.     }
  449.        ifelse
  450.      }
  451.     ifelse
  452.    end
  453.  } bind def
  454.  
  455. % Make the call on setcachedevice a separate procedure,
  456. % so we can redefine it if the composite font extensions are present.
  457. % (We don't use the obvious
  458. %    /setcachedevice_C /setcachedevice load def
  459. % because that would bind it into outline_C.)
  460. /setcachedevice_C { setcachedevice } bind def
  461.  
  462. /outline_C        % <charname> <charstring> -> -
  463.  { currentdict /Metrics .knownget
  464.     { 2 index .knownget
  465.        { dup type dup /integertype eq exch /realtype eq or
  466.           {    % <wx>
  467.         exch .type1addpath 0
  468.       }
  469.       { dup length 2 eq
  470.          {    % [<wx> <sbx>]
  471.            exch 1 index 0 get 0 .type1addpath
  472.            1 get 0
  473.          }
  474.          {    % [<wx> <wy> <sbx> <sby>]
  475.            aload pop 5 -1 roll 3 1 roll .type1addpath
  476.          }
  477.         ifelse
  478.       }
  479.      ifelse
  480.        }
  481.        { .type1addpath currentpoint
  482.        }
  483.       ifelse
  484.     }
  485.     { .type1addpath currentpoint
  486.     }
  487.    ifelse        % stack: wx wy
  488.    pathbbox
  489.    PaintType 0 ne
  490.     {        % Expand the bounding box by the stroke width.
  491.         % (Actually, only half the stroke width is needed.)
  492.       4 -1 roll currentlinewidth sub
  493.       4 -1 roll currentlinewidth sub
  494.       4 -1 roll currentlinewidth add
  495.       4 -1 roll currentlinewidth add
  496.     }
  497.    if
  498.    setcachedevice_C
  499.    PaintType 0 eq { fill } { stroke } ifelse
  500.    pop
  501.  } bind def
  502.  
  503. % Find all the precompiled font operators in systemdict.
  504.    systemdict
  505.     { exch =string cvs (.font_) anchorsearch
  506.        { pop pop exec    % execute the operator, returns the font dictionary
  507.          dup begin
  508.        Encoding type /stringtype eq
  509.         { Encoding cvn cvx exec /Encoding exch def
  510.         }
  511.        if
  512.        FontName exch
  513.      end definefont pop
  514.        }
  515.        { pop pop
  516.        }
  517.       ifelse
  518.     }
  519.    forall
  520.  
  521.  
  522.  
  523. % Define a procedure to load all known fonts.
  524. % This isn't likely to be very useful.
  525. /loadallfonts
  526.  { Fontmap { pop findfont pop } forall
  527.  } bind def
  528.